/*

This file is part of buco.  
Copyright (c) 2012 Christopher Pawelzik <christopher@cpawelzik.com>

Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php 
*/ 
package buco.core.internal;

import java.io.IOException;
import java.util.*;
import java.util.jar.*;

import buco.core.api.*;

/**
 * @author Christopher
 * 
 * This filter processes the JAR manifest and the OSGi-Metadata
 *
 */
public class ManifestFilter implements Filter<ProcessJarContext> {
	
	@Override
	public ProcessJarContext process(ProcessJarContext ctx) {
		try {
			Manifest manifest = ctx.getJarFile().getManifest();
			Bundle bundle = ctx.getBundle();
			
			// OSGi Attributes are in the default Namespace 
			Attributes attributes = manifest.getMainAttributes();
			
			String bundleSymbolicName = attributes.getValue("Bundle-SymbolicName");
			if(bundleSymbolicName == null) {
				throw new NoBundleException(); 			
			}
			
			HeaderElement symbolicNameHeader = HeaderParser.parseHeaderValue(bundleSymbolicName).get(0);
			bundleSymbolicName = symbolicNameHeader.getName();
			
			String bundleName = attributes.getValue("Bundle-Name");
			String bundleVersion = attributes.getValue("Bundle-Version");
			String bundleDescription = attributes.getValue("Bundle-Description");
			
			bundle.setBundleSymbolicName(bundleSymbolicName);
			bundle.setBundleName(bundleName); 
			bundle.setBundleVersion(Version.fromString(bundleVersion)); 
			bundle.setBundleDescription(bundleDescription); 
			
			// Parse export/import package header 
			String importPackage = attributes.getValue("Import-Package");
			if(importPackage != null && importPackage.length() > 0) {
				List<HeaderElement> imports = HeaderParser.parseHeaderValue(importPackage);
				processImports(bundle, imports);
			}
			
			String exportPackage = attributes.getValue("Export-Package");
			if(exportPackage != null && exportPackage.length() > 0) {
				List<HeaderElement> exports = HeaderParser.parseHeaderValue(exportPackage);
				processExports(bundle, exports);
			}
			
			String requireBundle = attributes.getValue("Require-Bundle"); 
			if(requireBundle != null && requireBundle.length() > 0 ) { 
				List<HeaderElement> requiredBundles = HeaderParser.parseHeaderValue(requireBundle);
				processRequiredBundles(bundle, requiredBundles); 
			}		
		} catch (NoBundleException e) {
			e.printStackTrace();
			return null;
		} catch (IOException e) {
			e.printStackTrace();
			return null;
		} 
		return ctx;
	}
	
	private void processImports(Bundle bundle, List<HeaderElement> imports) { 
		for(HeaderElement element : imports) {
			ImportPackageRequirement ir = new ImportPackageRequirement();
			ir.setPackageName(element.getName()); 
			Attribute versionAttr = element.getAttributeFromKey("version"); 
			if(versionAttr != null) {
				ir.setPackageVersionRange(VersionRange.fromString(versionAttr.getValue()));  
			}
			// Add other attributes ... 
			bundle.addRequirement(ir); 			
		}
	}

	private void processExports(Bundle bundle, List<HeaderElement> exports) {				
		for(HeaderElement element : exports) {
			ExportPackageCapability epc = new ExportPackageCapability();
			epc.setPackageName(element.getName());
			Attribute versionAttr = element.getAttributeFromKey("version"); 
			if(versionAttr != null) {
				epc.setPackageVersion(Version.fromString(versionAttr.getValue())); 
			}
			bundle.addCapability(epc); 
		}
	}
	
	private void processRequiredBundles(Bundle bundle, List<HeaderElement> requiredBundles) {
		for(HeaderElement element : requiredBundles) {
			RequireBundleRequirement rbr = new RequireBundleRequirement(element.getName());
			Attribute versionAttr = element.getAttributeFromKey("version");
			if(versionAttr != null) {
				rbr.setBundleVersion(VersionRange.fromString(versionAttr.getValue())); 
			}
			bundle.addRequirement(rbr);
		}
	}
	
}
